#include <stdio.h>
#include <SDL3/sdl.h>

#include "../lib/lua/src/lua.h"
#include "../lib/lua/src/lualib.h"
#include "../lib/lua/src/lauxlib.h"

#define FALSE 0
#define TRUE 1
#define WINDOW_WIDTH 1920
#define WINDOW_HEIGHT 1080
#define FPS 60
#define FRAME_DELAY (1000 / FPS)

struct player{
    float x;
    float y;
    float width;
    float height;
} player;

void execute_lua_example(void);

SDL_Window* window = NULL;
SDL_Renderer* renderer = NULL;
int is_running = FALSE;
Uint32 frameStart, frameTime, lastUpdateTime;
float deltaTime;
lua_State* ls;

int initialize_window(void){
    if (SDL_Init(SDL_INIT_VIDEO) == false){
        fprintf(stderr, "Error initializing SDL.\n");
        return FALSE;
    }

    window = SDL_CreateWindow("LUA", WINDOW_WIDTH, WINDOW_HEIGHT, SDL_WINDOW_RESIZABLE);
    if (!window){
        fprintf(stderr, "Error createing SDL window.\n");
        return FALSE;
    }
    SDL_SetWindowPosition(window, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED);

    renderer = SDL_CreateRenderer(window, NULL);
    if (!renderer){
        fprintf(stderr, "Error createing SDL renderer.\n");
        return FALSE;
    }

    return TRUE;
}

void process_input(void){
    SDL_Event event;    
    SDL_PollEvent(&event);
    switch (event.type){
        case SDL_EVENT_QUIT: {
            is_running = false;
            break;
        }
        case SDL_EVENT_KEY_DOWN:{
            if (event.key.key == SDLK_ESCAPE){
                is_running = false;
            }
            break;
        }
        
    }
}

void setup(void){
    player.x = 20;
    player.y = 20;
    player.width = 50;
    player.height = 50;

    // 这是为了防止deltaTime过大
    lastUpdateTime = SDL_GetTicks();
}

void update(void){
    frameStart = SDL_GetTicks(); // 记录帧开始时间
    // 计算deltaTime
    Uint32 currentTime = SDL_GetTicks();
    deltaTime = (currentTime - lastUpdateTime) / 1000.0f; // 转换为秒
    if (deltaTime > FRAME_DELAY){
        deltaTime = FRAME_DELAY;
    }
    lastUpdateTime = currentTime; // 更新上一帧Update的时间

    // 游戏实际逻辑
    lua_getglobal(ls, "update");
    if (lua_isfunction(ls, -1)){
        const int NUM_ARGS = 1;
        const int NUM_RETURNS = 0;
        lua_pushnumber(ls, deltaTime);
        lua_pcall(ls, NUM_ARGS, NUM_RETURNS, 0);
    }
    //player.x += 100.0f * deltaTime;
    //player.y += 100.0f * deltaTime;

    
    // 计算帧执行时间
    frameTime = SDL_GetTicks() - frameStart;
    // 延迟剩余时间
    if (frameTime < FRAME_DELAY) {
        SDL_Delay(FRAME_DELAY - frameTime);
    }
}

void render(void){
    SDL_SetRenderDrawColor(renderer, 0, 128, 128, 255);
    SDL_RenderClear(renderer);

    // TODO:这里进行对象的渲染
    SDL_SetRenderDrawColor(renderer, 255,0,0,255);
    SDL_FRect player_rect = {player.x, player.y, player.width, player.height};
    SDL_RenderFillRect(renderer, &player_rect);

    SDL_RenderPresent(renderer);
}

void destroy_window(void){
    SDL_DestroyRenderer(renderer);
    SDL_DestroyWindow(window);
    SDL_Quit();
}

int set_player_pos(lua_State* l){
    lua_Number x = lua_tonumber(l, -2);
    lua_Number y = lua_tonumber(l, -1);
    player.x = x;
    player.y = y;
    return 0;
}

int main(int argc, char* argv[]){
    printf("Hello! Lua!\n");

    ls = luaL_newstate();
    luaL_openlibs(ls);
    if (luaL_dofile(ls, "./scripts/playermovement.lua") != LUA_OK){
         luaL_error(ls, "playermovement.lua Error: %s\n", lua_tostring(ls, -1));
         return TRUE;
    }
    lua_pushcfunction(ls, set_player_pos);
    lua_setglobal(ls, "set_player_pos");

    //execute_lua_example();

    is_running = initialize_window();

    setup();

    while (is_running) {      

        process_input();
        update();
        render();
    }
    destroy_window();
    
    return 0;
}